package UML_ER.diagram.providers;

import java.util.HashSet;
import java.util.IdentityHashMap;
import java.util.Map;
import java.util.Set;

import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EClassifier;
import org.eclipse.emf.ecore.ENamedElement;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.gmf.runtime.emf.type.core.ElementTypeRegistry;
import org.eclipse.gmf.runtime.emf.type.core.IElementType;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.resource.ImageRegistry;
import org.eclipse.swt.graphics.Image;

import UML_ER.UML_ERPackage;
import UML_ER.diagram.edit.parts.AggregationEditPart;
import UML_ER.diagram.edit.parts.Attribute2EditPart;
import UML_ER.diagram.edit.parts.AttributeEditPart;
import UML_ER.diagram.edit.parts.BinaryRelationship2EditPart;
import UML_ER.diagram.edit.parts.BinaryRelationshipEditPart;
import UML_ER.diagram.edit.parts.BinaryRelationshipTargetEditPart;
import UML_ER.diagram.edit.parts.CompositionEditPart;
import UML_ER.diagram.edit.parts.ERmodelEditPart;
import UML_ER.diagram.edit.parts.EntityEditPart;
import UML_ER.diagram.edit.parts.GeneralizationEditPart;
import UML_ER.diagram.edit.parts.OntologyReference2EditPart;
import UML_ER.diagram.edit.parts.OntologyReferenceEditPart;
import UML_ER.diagram.edit.parts.OntologyReferenceRelationshipEditPart;
import UML_ER.diagram.edit.parts.RelationshipEditPart;
import UML_ER.diagram.edit.parts.RoleEditPart;
import UML_ER.diagram.part.UML_ERDiagramEditorPlugin;

/**
 * 
 */
public class UML_ERElementTypes {

	/**
	 * @generated
	 */
	private UML_ERElementTypes() {
	}

	/**
	 * @generated
	 */
	private static Map<IElementType, ENamedElement> elements;

	/**
	 * @generated
	 */
	private static ImageRegistry imageRegistry;

	/**
	 * @generated
	 */
	private static Set<IElementType> KNOWN_ELEMENT_TYPES;

	/**
	 * @generated
	 */
	public static final IElementType ERmodel_1000 = getElementType("UML_ER.diagram.ERmodel_1000"); //$NON-NLS-1$
	/**
	 * @generated
	 */
	public static final IElementType Entity_2003 = getElementType("UML_ER.diagram.Entity_2003"); //$NON-NLS-1$

	/**
	 * @generated
	 */
	public static final IElementType BinaryRelationship_2008 = getElementType("UML_ER.diagram.BinaryRelationship_2008"); //$NON-NLS-1$

	/**
	 * @generated
	 */
	public static final IElementType Relationship_2009 = getElementType("UML_ER.diagram.Relationship_2009"); //$NON-NLS-1$

	/**
	 * @generated
	 */
	public static final IElementType Attribute_3001 = getElementType("UML_ER.diagram.Attribute_3001"); //$NON-NLS-1$

	/**
	 * @generated
	 */
	public static final IElementType OntologyReference_3002 = getElementType("UML_ER.diagram.OntologyReference_3002"); //$NON-NLS-1$

	/**
	 * @generated
	 */
	public static final IElementType Attribute_3003 = getElementType("UML_ER.diagram.Attribute_3003"); //$NON-NLS-1$

	/**
	 * @generated
	 */
	public static final IElementType Generalization_4011 = getElementType("UML_ER.diagram.Generalization_4011"); //$NON-NLS-1$

	/**
	 * @generated
	 */
	public static final IElementType Role_4024 = getElementType("UML_ER.diagram.Role_4024"); //$NON-NLS-1$

	/**
	 * @generated
	 */
	public static final IElementType Composition_4025 = getElementType("UML_ER.diagram.Composition_4025"); //$NON-NLS-1$

	/**
	 * @generated
	 */
	public static final IElementType BinaryRelationship_4014 = getElementType("UML_ER.diagram.BinaryRelationship_4014"); //$NON-NLS-1$

	/**
	 * @generated
	 */
	public static final IElementType Aggregation_4015 = getElementType("UML_ER.diagram.Aggregation_4015"); //$NON-NLS-1$

	/**
	 * @generated
	 */
	public static final IElementType BinaryRelationshipTarget_4022 = getElementType("UML_ER.diagram.BinaryRelationshipTarget_4022"); //$NON-NLS-1$

	public static final IElementType OntologyReferenceRelationship_3010 = getElementType("UML_ER.diagram.OntologyReferenceRelationship_3010"); //$NON-NLS-1$

	/**
	 * @generated
	 */
	private static ImageRegistry getImageRegistry() {
		if (imageRegistry == null) {
			imageRegistry = new ImageRegistry();
		}
		return imageRegistry;
	}

	/**
	 * @generated
	 */
	private static String getImageRegistryKey(ENamedElement element) {
		return element.getName();
	}

	/**
	 * @generated
	 */
	private static ImageDescriptor getProvidedImageDescriptor(
			ENamedElement element) {
		if (element instanceof EStructuralFeature) {
			EStructuralFeature feature = ((EStructuralFeature) element);
			EClass eContainingClass = feature.getEContainingClass();
			EClassifier eType = feature.getEType();
			if (eContainingClass != null && !eContainingClass.isAbstract()) {
				element = eContainingClass;
			} else if (eType instanceof EClass
					&& !((EClass) eType).isAbstract()) {
				element = eType;
			}
		}
		if (element instanceof EClass) {
			EClass eClass = (EClass) element;
			if (!eClass.isAbstract()) {
				return UML_ERDiagramEditorPlugin.getInstance()
						.getItemImageDescriptor(
								eClass.getEPackage().getEFactoryInstance()
										.create(eClass));
			}
		}
		// TODO : support structural features
		return null;
	}

	/**
	 * @generated
	 */
	public static ImageDescriptor getImageDescriptor(ENamedElement element) {
		String key = getImageRegistryKey(element);
		ImageDescriptor imageDescriptor = getImageRegistry().getDescriptor(key);
		if (imageDescriptor == null) {
			imageDescriptor = getProvidedImageDescriptor(element);
			if (imageDescriptor == null) {
				imageDescriptor = ImageDescriptor.getMissingImageDescriptor();
			}
			getImageRegistry().put(key, imageDescriptor);
		}
		return imageDescriptor;
	}

	/**
	 * @generated
	 */
	public static Image getImage(ENamedElement element) {
		String key = getImageRegistryKey(element);
		Image image = getImageRegistry().get(key);
		if (image == null) {
			ImageDescriptor imageDescriptor = getProvidedImageDescriptor(element);
			if (imageDescriptor == null) {
				imageDescriptor = ImageDescriptor.getMissingImageDescriptor();
			}
			getImageRegistry().put(key, imageDescriptor);
			image = getImageRegistry().get(key);
		}
		return image;
	}

	/**
	 * @generated
	 */
	public static ImageDescriptor getImageDescriptor(IAdaptable hint) {
		ENamedElement element = getElement(hint);
		if (element == null) {
			return null;
		}
		return getImageDescriptor(element);
	}

	/**
	 * @generated
	 */
	public static Image getImage(IAdaptable hint) {
		ENamedElement element = getElement(hint);
		if (element == null) {
			return null;
		}
		return getImage(element);
	}

	/**
	 * Returns 'type' of the ecore object associated with the hint.
	 * 
	 * 
	 */
	public static ENamedElement getElement(IAdaptable hint) {
		Object type = hint.getAdapter(IElementType.class);
		if (elements == null) {
			elements = new IdentityHashMap<IElementType, ENamedElement>();

			elements.put(ERmodel_1000, UML_ERPackage.eINSTANCE.getERmodel());

			elements.put(Entity_2003, UML_ERPackage.eINSTANCE.getEntity());

			elements.put(BinaryRelationship_2008,
					UML_ERPackage.eINSTANCE.getBinaryRelationship());

			elements.put(Relationship_2009,
					UML_ERPackage.eINSTANCE.getRelationship());

			elements.put(Role_4024,
					UML_ERPackage.eINSTANCE.getRole_Relationship());

			elements.put(Attribute_3001, UML_ERPackage.eINSTANCE.getAttribute());

			elements.put(OntologyReference_3002,
					UML_ERPackage.eINSTANCE.getOntologyReference());

			elements.put(Attribute_3003, UML_ERPackage.eINSTANCE.getAttribute());

			elements.put(Generalization_4011,
					UML_ERPackage.eINSTANCE.getGeneralization());

			elements.put(BinaryRelationship_4014,
					UML_ERPackage.eINSTANCE.getBinaryRelationship());

			elements.put(Aggregation_4015,
					UML_ERPackage.eINSTANCE.getAggregation());

			elements.put(Composition_4025,
					UML_ERPackage.eINSTANCE.getComposition());

		}
		return (ENamedElement) elements.get(type);
	}

	/**
	 * @generated
	 */
	private static IElementType getElementType(String id) {
		return ElementTypeRegistry.getInstance().getType(id);
	}

	/**
	 * @generated
	 */
	public static boolean isKnownElementType(IElementType elementType) {
		if (KNOWN_ELEMENT_TYPES == null) {
			KNOWN_ELEMENT_TYPES = new HashSet<IElementType>();
			KNOWN_ELEMENT_TYPES.add(ERmodel_1000);
			KNOWN_ELEMENT_TYPES.add(Entity_2003);
			KNOWN_ELEMENT_TYPES.add(BinaryRelationship_2008);
			KNOWN_ELEMENT_TYPES.add(Relationship_2009);
			KNOWN_ELEMENT_TYPES.add(Attribute_3001);
			KNOWN_ELEMENT_TYPES.add(OntologyReference_3002);
			KNOWN_ELEMENT_TYPES.add(Attribute_3003);
			KNOWN_ELEMENT_TYPES.add(BinaryRelationship_4014);
			KNOWN_ELEMENT_TYPES.add(Aggregation_4015);
			KNOWN_ELEMENT_TYPES.add(BinaryRelationshipTarget_4022);
			KNOWN_ELEMENT_TYPES.add(Generalization_4011);
			KNOWN_ELEMENT_TYPES.add(Role_4024);
			KNOWN_ELEMENT_TYPES.add(Composition_4025);
		}
		return KNOWN_ELEMENT_TYPES.contains(elementType);
	}

	/**
	 * @generated
	 */
	public static IElementType getElementType(int visualID) {
		switch (visualID) {
		case ERmodelEditPart.VISUAL_ID:
			return ERmodel_1000;
		case EntityEditPart.VISUAL_ID:
			return Entity_2003;
		case BinaryRelationshipEditPart.VISUAL_ID:
			return BinaryRelationship_2008;
		case RelationshipEditPart.VISUAL_ID:
			return Relationship_2009;
		case AttributeEditPart.VISUAL_ID:
			return Attribute_3001;
		case OntologyReferenceEditPart.VISUAL_ID:
			return OntologyReference_3002;
		case Attribute2EditPart.VISUAL_ID:
			return Attribute_3003;
		case BinaryRelationship2EditPart.VISUAL_ID:
			return BinaryRelationship_4014;
		case AggregationEditPart.VISUAL_ID:
			return Aggregation_4015;
		case BinaryRelationshipTargetEditPart.VISUAL_ID:
			return BinaryRelationshipTarget_4022;
		case GeneralizationEditPart.VISUAL_ID:
			return Generalization_4011;
		case RoleEditPart.VISUAL_ID:
			return Role_4024;
		case CompositionEditPart.VISUAL_ID:
			return Composition_4025;
		}
		return null;
	}

}
